package com.anysoft.service;

import android.app.Notification;
import android.app.PendingIntent;
import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.net.Uri;
import android.os.Build;
import android.os.Environment;
import android.os.Handler;
import android.os.IBinder;
import android.support.v4.app.NotificationCompat;
import android.support.v4.app.NotificationManagerCompat;
import android.support.v4.content.FileProvider;
import android.support.v4.content.LocalBroadcastManager;

import com.aspsine.multithreaddownload.CallBack;
import com.aspsine.multithreaddownload.DownloadException;
import com.aspsine.multithreaddownload.DownloadManager;
import com.aspsine.multithreaddownload.DownloadRequest;
import com.aspsine.multithreaddownload.util.L;
import com.anysoft.MentorApplication;
import com.anysoft.R;
import com.anysoft.bean.AppInfo;
import com.anysoft.me.config.CommentConfig;
import com.anysoft.utils.OpenFileTipDialog;
import com.anysoft.utils.Utils;

import java.io.File;

import static com.anysoft.MentorApplication.context;

/**
 * Created by aspsine on 15/7/28.
 */
public class DownloadService extends Service {

    private static final String TAG = DownloadService.class.getSimpleName();

    /**
     * Dir: /Download
     */
    private static File mDownloadDir;
    
    private DownloadManager mDownloadManager;
    private NotificationManagerCompat mNotificationManager;

    @Override
    public void onCreate() {
        super.onCreate();
        mDownloadManager = DownloadManager.getInstance();
        mNotificationManager = NotificationManagerCompat.from(getApplicationContext());
        mDownloadDir = Environment.getExternalStoragePublicDirectory(CommentConfig.DOWNLOAD_DIR_NAME);
    }
    
    public static void intentDownload(Context context, int position, String tag, AppInfo info) {
        Intent intent = new Intent(context, DownloadService.class);
        intent.setAction(CommentConfig.ACTION_DOWNLOAD);
        intent.putExtra(CommentConfig.EXTRA_POSITION, position);
        intent.putExtra(CommentConfig.EXTRA_TAG, tag);
        intent.putExtra(CommentConfig.EXTRA_APP_INFO, info);
        context.startService(intent);
    }
    
    public static void intentPause(Context context, String tag) {
        Intent intent = new Intent(context, DownloadService.class);
        intent.setAction(CommentConfig.ACTION_PAUSE);
        intent.putExtra(CommentConfig.EXTRA_TAG, tag);
        context.startService(intent);
    }
    
    public static void intentPauseAll(Context context) {
        Intent intent = new Intent(context, DownloadService.class);
        context.startService(intent);
    }
    
    public static void destory(Context context) {
        Intent intent = new Intent(context, DownloadService.class);
        context.stopService(intent);
    }
    
    @Override
    public IBinder onBind(Intent intent) {
        return null;
    }
    
    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        if (intent != null) {
            String action = intent.getAction();
            int position = intent.getIntExtra(CommentConfig.EXTRA_POSITION, 0);
            AppInfo appInfo = (AppInfo) intent.getSerializableExtra(CommentConfig.EXTRA_APP_INFO);
            String tag = intent.getStringExtra(CommentConfig.EXTRA_TAG);
            switch (action) {
                case CommentConfig.ACTION_DOWNLOAD:
                    download(position, appInfo, tag);
                    break;
                case CommentConfig.ACTION_PAUSE:
                    pause(tag);
                    break;
                case CommentConfig.ACTION_CANCEL:
                    cancel(tag);
                    break;
                case CommentConfig.ACTION_PAUSE_ALL:
                    pauseAll();
                    break;
                case CommentConfig.ACTION_CANCEL_ALL:
                    cancelAll();
                    break;
            }
        }
        return super.onStartCommand(intent, flags, startId);
    }
    
    private void download(final int position, final AppInfo appInfo, String tag) {
        final DownloadRequest request = new DownloadRequest.Builder()
                .setName(appInfo.getName())
                .setUri(appInfo.getUrl())
                .setFolder(mDownloadDir)
                .build();
        mDownloadManager.download(request, tag, new DownloadCallBack(position, appInfo, mNotificationManager, getApplicationContext()));
    }
    
    private void pause(String tag) {
        mDownloadManager.pause(tag);
    }
    
    private void cancel(String tag) {
        mDownloadManager.cancel(tag);
    }
    
    private void pauseAll() {
        mDownloadManager.pauseAll();
    }
    
    private void cancelAll() {
        mDownloadManager.cancelAll();
    }
    
    @Override
    public void onDestroy() {
        super.onDestroy();
        mDownloadManager.pauseAll();
    }
    
    public static class DownloadCallBack implements CallBack {
        
        private int mPosition;
        
        private AppInfo mAppInfo;
        
        private LocalBroadcastManager mLocalBroadcastManager;
        
        private NotificationCompat.Builder mBuilder;
        
        private NotificationManagerCompat mNotificationManager;
        
        private long mLastTime;
        
        public DownloadCallBack(int position, AppInfo appInfo, NotificationManagerCompat notificationManager, Context context) {
            mPosition = position;
            mAppInfo = appInfo;
            mNotificationManager = notificationManager;
            mLocalBroadcastManager = LocalBroadcastManager.getInstance(context);
            mBuilder = new NotificationCompat.Builder(context);
            mBuilder.setOngoing(true)
                    .setAutoCancel(true);
        }
        
        @Override
        public void onStarted() {
            L.i(TAG, "onStart()");
            mBuilder.setSmallIcon(R.mipmap.icon_logo)
                    .setContentTitle(mAppInfo.getName())
                    .setContentText("开始下载...")
                    .setProgress(100, 0, true)
                    .setTicker("开始下载" + mAppInfo.getName());
            updateNotification();
        }
        
        @Override
        public void onConnecting() {
            L.i(TAG, "onConnecting()");
            mBuilder.setContentText("开始下载...")
                    .setProgress(100, 0, true);
            updateNotification();
            
            mAppInfo.setStatus(AppInfo.STATUS_CONNECTING);
            sendBroadCast(mAppInfo);
        }
        
        @Override
        public void onConnected(long total, boolean isRangeSupport) {
            L.i(TAG, "onConnected()");
            mBuilder.setContentText("开始下载...")
                    .setProgress(100, 0, true);
            updateNotification();
        }
        
        @Override
        public void onProgress(long finished, long total, int progress) {
            
            if (mLastTime == 0) {
                mLastTime = System.currentTimeMillis();
            }
            mAppInfo.setStatus(AppInfo.STATUS_DOWNLOADING);
            mAppInfo.setProgress(progress);
            mAppInfo.setDownloadPerSize(Utils.getDownloadPerSize(finished, total));
            long currentTime = System.currentTimeMillis();
            if (currentTime - mLastTime > 500) {
                L.i(TAG, "onProgress()");
                mBuilder.setContentText("正在下载...");
                mBuilder.setProgress(100, progress, false);
                updateNotification();
                sendBroadCast(mAppInfo);
                mLastTime = currentTime;
            }
        }
        
        @Override
        public void onCompleted() {
            L.i(TAG, "onCompleted()");
            mBuilder.setContentText("下载完成啦");
            mBuilder.setProgress(0, 0, false);
            mBuilder.setTicker(mAppInfo.getName() + "下载完成");
            Uri uri = null;
            Intent intent = new Intent();
            intent.setAction(Intent.ACTION_VIEW);
            intent.addCategory(Intent.CATEGORY_DEFAULT);
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
                intent.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
                uri = FileProvider.getUriForFile(context, "com.anysoft.fileprovider", new File
                        (mDownloadDir, mAppInfo.getName()));
            } else {
                uri = Uri.fromFile(new File(mDownloadDir, mAppInfo.getName()));
                intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
            }
            String type = OpenFileTipDialog.getMIMEType(new File
                    (mDownloadDir, mAppInfo.getName()).toString());
            intent.setDataAndType(uri, type);
            PendingIntent pendingIntent = PendingIntent.getActivity(context, 0, intent, 0);
            mBuilder.setContentIntent(pendingIntent);
            mBuilder.setOngoing(true)
                    .setAutoCancel(true)
                    .setPriority(Notification.PRIORITY_MAX)
                    .setFullScreenIntent(pendingIntent, true)
                    .setDefaults(Notification.DEFAULT_ALL);

            updateNotification();
            mAppInfo.setStatus(AppInfo.STATUS_COMPLETE);
            mAppInfo.setProgress(100);
            sendBroadCast(mAppInfo, CommentConfig.ACTION_DOWNLOAD_COMPLITE);
        }
        
        @Override
        public void onDownloadPaused() {
            L.i(TAG, "onDownloadPaused()");
            mBuilder.setContentText("下载暂停啦");
            mBuilder.setTicker(mAppInfo.getName() + "下载暂停");
            mBuilder.setProgress(100, mAppInfo.getProgress(), false)
                    .setAutoCancel(true);
            mBuilder.build().flags |= Notification.FLAG_NO_CLEAR;
            updateNotification();
            mAppInfo.setStatus(AppInfo.STATUS_PAUSED);
            sendBroadCast(mAppInfo);
        }
        
        @Override
        public void onDownloadCanceled() {
            L.i(TAG, "onDownloadCanceled()");
            mBuilder.setContentText("下载取消啦");
            mBuilder.setTicker(mAppInfo.getName() + "下载取消");
            mBuilder.build().flags |= Notification.FLAG_NO_CLEAR;
            updateNotification();
            
            new Handler().postDelayed(new Runnable() {
                @Override
                public void run() {
                    mNotificationManager.cancel(mPosition + 1000);
                }
            }, 3000);
            
            mAppInfo.setStatus(AppInfo.STATUS_NOT_DOWNLOAD);
            mAppInfo.setProgress(0);
            mAppInfo.setDownloadPerSize("");
            destory(MentorApplication.context);
            sendBroadCast(mAppInfo);
        }
        
        @Override
        public void onFailed(DownloadException e) {
            L.i(TAG, "onFailed()");
            e.printStackTrace();
            mBuilder.setContentText("下载失败啦");
            mBuilder.setTicker(mAppInfo.getName() + "下载失败");
            mBuilder.setProgress(100, mAppInfo.getProgress(), false);
            mBuilder.build().flags |= Notification.FLAG_NO_CLEAR;
            updateNotification();
            new Handler().postDelayed(new Runnable() {
                @Override
                public void run() {
                    mNotificationManager.cancel(mPosition + 1000);
                }
            }, 3000);
            destory(MentorApplication.context);
            mAppInfo.setStatus(AppInfo.STATUS_DOWNLOAD_ERROR);
            sendBroadCast(mAppInfo);
        }
        
        private void updateNotification() {
            mNotificationManager.notify(mPosition + 1000, mBuilder.build());
        }
        
        private void sendBroadCast(AppInfo appInfo) {
            Intent intent = new Intent();
            intent.setAction(CommentConfig.ACTION_DOWNLOAD_BROAD_CAST);
            intent.putExtra(CommentConfig.EXTRA_POSITION, mPosition);
            intent.putExtra(CommentConfig.EXTRA_APP_INFO, appInfo);
            mLocalBroadcastManager.sendBroadcast(intent);
        }
        
        private void sendBroadCast(AppInfo appInfo, String action) {
            Intent intent = new Intent();
            intent.setAction(action);
            intent.putExtra(CommentConfig.EXTRA_POSITION, mPosition);
            intent.putExtra(CommentConfig.EXTRA_APP_INFO, appInfo);
            mLocalBroadcastManager.sendBroadcast(intent);
        }
    }
    
}
